/**
 * @file fsm.c
 * @author chenzhanzhan
 * @brief 简易有限状态机实现
 * @note ST_FSM_CLASS一定要通过FsmObjInit初始化，否则会出现未定义行为
 * @date 2024-10-03
 */
#include "Fsm.h"

static unsigned short FsmGetActIndex(ST_FSM_CLASS* pFsm,unsigned short u16StateID);

/**
 * @brief 初始化一个状态机
 * @param[in] pFsm 状态机对象
 * @param[in] pstEventMap 事件表
 * @param[in] pstActMap 动作表
 * @param[in] u16EventSum 事件表大小
 * @param[in] u16ActSum 动作表大小
 * @param[in] curState 当前状态
 * @param[in] pUserData 用户数据
 * @return 0:成功 -1:失败
 */
signed short FsmObjInit(ST_FSM_CLASS* pFsm,ST_FSM_EVENT* pstEventMap,ST_FSM_ACT *pstActMap,unsigned short u16EventSum,unsigned short u16ActSum,unsigned short curState,void* pUserData)
{
	if((NULL == pFsm) || (NULL == pstEventMap) || (NULL == pstActMap))
	{
		return -1;
	}
	pFsm->u16StateFlag = 0;
	pFsm->u16NextState = FSM_INVALID_STATE;
	pFsm->u16CurrentState = curState;
	pFsm->stEventMap.map = pstEventMap;
	pFsm->stActMap.map = pstActMap;
	pFsm->stEventMap.size = u16EventSum;
	pFsm->stActMap.size = u16ActSum;
	pFsm->pUserData = pUserData;
	return 0;
}

/**
 * @brief 状态机状态转移
 * @param[in] pFsm 状态机对象
 * @param[in] u16EventID 事件ID
 * @return 1:成功 -1:失败 0:无匹配事件
 */
signed short FsmStateTransfer(ST_FSM_CLASS* pFsm, unsigned short u16EventID)
{
	unsigned short i = 0;
	if(pFsm == NULL)
	{
		return -1;
	}
	for(i=0; i<pFsm->stEventMap.size; i++)
	{
		if((u16EventID == pFsm->stEventMap.map[i].u16EventID) && 
		   (pFsm->u16CurrentState == pFsm->stEventMap.map[i].u16CurrentState))
		{
			pFsm->u16NextState = pFsm->stEventMap.map[i].u16NextState;
			pFsm->u16StateFlag = 1;
			return 1;
		}
	}
	return 0;
}

/**
 * @brief 获取当前状态对应响应索引
 * @param[in] pFsm 状态机对象
 * @param[in] u16StateID 状态ID
 * @return 响应索引
 */
unsigned short FsmGetActIndex(ST_FSM_CLASS* pFsm,unsigned short u16StateID)
{
	unsigned short i = 0;
	if(NULL == pFsm)
	{
		return FSM_INVALID_STATE;
	}
	for(i = 0; i < pFsm->stActMap.size; i ++)
	{
		if(u16StateID == pFsm->stActMap.map[i].u16StateID)
		{
			return i;
		}	
	}
	return FSM_INVALID_STATE;
}

/**
 * @brief 执行动作
 * @param[in] pFsm 状态机对象
 * @return 0:成功 -1:失败
 */
signed short FsmActionPerfrom(ST_FSM_CLASS* pFsm)
{
	unsigned short u16CurID = FSM_INVALID_STATE;
	unsigned short u16NextID = FSM_INVALID_STATE;

	if(NULL == pFsm)
	{
		return -1;
	}
	
	if(0 != pFsm->u16StateFlag)	
	{
		u16CurID = FsmGetActIndex(pFsm,pFsm->u16CurrentState);
		u16NextID = FsmGetActIndex(pFsm,pFsm->u16NextState);
		
		if((FSM_INVALID_STATE != u16CurID) && (FSM_INVALID_STATE != u16NextID))
		{
			/* 执行当前状态的退出动作 */
            if(pFsm->stActMap.map[u16CurID].ExitActCallback)
            {
			    pFsm->stActMap.map[u16CurID].ExitActCallback(pFsm->pUserData);
            }
			/* 执行下一个状态的进入动作 */	
            if(pFsm->stActMap.map[u16NextID].EnterActCallback) 
            {
			    pFsm->stActMap.map[u16NextID].EnterActCallback(pFsm->pUserData);
            }
            pFsm->u16CurrentState = pFsm->u16NextState;			
            pFsm->u16NextState = FSM_INVALID_STATE;	
		}
		else
		{
			pFsm->u16StateFlag = 0;								
			return -1;
		}							
	}
	else
	{
		u16CurID = FsmGetActIndex(pFsm,pFsm->u16CurrentState);
		if(FSM_INVALID_STATE != u16CurID)
		{
            if(pFsm->stActMap.map[u16CurID].RunActCallback)
            {
			    pFsm->stActMap.map[u16CurID].RunActCallback(pFsm->pUserData);
            }
		}
	}
	return 0;	
}
